package main

import (
	"github.com/consensys/gnark/frontend"
	"github.com/consensys/gnark/std/hash/mimc"
)

//
//import (
//	"github.com/consensys/gnark/frontend"
//	"github.com/consensys/gnark/std/hash/mimc"
//)
//
//type Circuit struct {
//	Mx        frontend.Variable `gnark:",public"`
//	Cloud_HMx frontend.Variable
//	//Cloud_SHMx [][]frontend.Variable `gnark:",public"`
//	//r          frontend.Variable     `gnark:",public"`
//}
//
////func (circuit *Circuit) Add(Mx [][]*pbc.Element) error {
////	for i, row := range Mx {
////		for j, elem := range row {
////			circuit.Mx[i][j] = elem
////		}
////	}
////	return nil
////}
//
////func (circuit *Circuit) Define(api frontend.API) error {
////	// create the mc hash function
////	mc, _ := mimc.NewMiMC(api)
////	api.Println("Mx", circuit.Mx)
////	api.Println("HMx", circuit.Cloud_HMx)
////	mc.Write(circuit.Mx)
////	api.Println("mc.Sum()", mc.Sum())
////	api.AssertIsEqual(mc.Sum(), circuit.Cloud_HMx)
////	//for i := 0; i < len(circuit.Mx); i++ {
////	//	for j := 0; j < len(circuit.Mx[0]); j++ {
////	//		// hash the current element in Mx using mc
////	//		mc.Write(circuit.Mx[i][j])
////	//		h := mc.Sum()
////	//		// create a constraint for the current element in HMx
////	//	}
////	//}
////
////	//SHMx := make([][]frontend.Variable, len(circuit.Mx))
////	//for i := range HMx {
////	//	SHMx[i] = make([]frontend.Variable, len(circuit.Mx[i]))
////	//}
////	//for i, row := range HMx {
////	//	for j, elem := range row {
////	//		temp := cs.Add(elem, circuit.r)
////	//		mc.Write(temp)
////	//		SHMx[i][j] = mc.Sum()
////	//	}
////	//}
////	//for i, row := range SHMx {
////	//	for j, elem := range row {
////	//		cs.AssertIsEqual(elem, circuit.Cloud_SHMx[i][j])
////	//	}
////	//}
////
////	return nil
////}
//
//func (circuit *Circuit) Define(api frontend.API) error {
//	api.Println(circuit.Mx)
//	api.Println(circuit.Cloud_HMx)
//
//	mimc, _ := mimc.NewMiMC(api)
//	mimc.Write(circuit.Mx)
//	api.Println(mimc.Sum())
//	api.AssertIsEqual(circuit.Cloud_HMx, mimc.Sum())
//	return nil
//}

type Circuit struct {
	Mx [][]frontend.Variable
	//Hash [][]frontend.Variable `gnark:",public"`
	chal []frontend.Variable `gnark:",secret"`
	//SHMx_all frontend.Variable     `gnark:"public"`
	HMx_all frontend.Variable `gnark:",public"`
}

func (circuit *Circuit) Define(api frontend.API) error {
	mimc, _ := mimc.NewMiMC(api)
	circuit_HMx_all := frontend.Variable(0)
	for i, row := range circuit.Mx {
		for _, elem := range row {
			// hash the current element in Mx using mc
			mimc.Write(elem)
			h := mimc.Sum()
			juhe := api.Mul(h, circuit.chal[i])
			//api.AssertIsEqual(circuit.Hash[i][j], juhe)
			circuit_HMx_all = api.Add(circuit_HMx_all, juhe)
			mimc.Reset()
			// create a constraint for the current element in HMx
		}
	}
	//api.AssertIsEqual(circuit_HMx_all, circuit.HMx_all)
	api.IsZero(circuit_HMx_all)
	api.IsZero(circuit.HMx_all)

	//for i, row := range circuit.Hash {
	//	for j, elem := range row {
	//		// hash the current element in Mx using mc
	//		mimc.Write(api.Add(elem, circuit.R))
	//		h := mimc.Sum()
	//		api.AssertIsEqual(circuit.SHash[i][j], h)
	//		mimc.Reset()
	//		// create a constraint for the current element in HMx
	//	}
	//}
	//circuit_SHMx_all := api.Add(circuit_HMx_all, circuit.R)
	//mimc.Write(circuit_SHMx_all)
	//hash := mimc.Sum()
	//api.IsZero(hash)
	//api.IsZero(circuit.SHMx_all)
	//api.Println("circuit_HMx_all", circuit_HMx_all)
	//api.Println("R", circuit.R)
	//api.Println("circuitHash", hash)
	//api.Println("R", circuit.R)

	//mimc.Write(circuit.Mx)
	//api.Println(mimc.Sum())
	//hash := mimc.Sum()
	//api.AssertIsEqual(circuit.Hash, hash)
	return nil
}
